﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tecnosop.Dominio;
using Tecnosop.WebUI.Models;
using Tecnosop.WebUI.Infrastructure.Notification;
using System.Data;
using System.Web.UI;

namespace Tecnosop.WebUI.Controllers
{
    [Authorize]
    public partial class ItemController : Controller
    {
        private Entidades db = new Entidades();

        #region CRUD

        public virtual ActionResult Index()
        {
            var items = db.ITEM.ToList();
            var itemsVM = new List<ItemViewModel>();
            foreach (var item in items)
            {
                itemsVM.Add(new ItemViewModel
                {
                    CODIGO_ITEM = item.CODIGO_ITEM,
                    MARCA = item.MARCA,
                    MODELO = item.MODELO,
                    PRECIO = item.PRECIO ?? 0,
                    //UNIDAD = item.UNIDAD,
                    Tipo = db.EQUIPO.Any(e => e.CODIGO_ITEM == item.CODIGO_ITEM) ? "Equipo" : "Insumo"
                });
            }

            return View(itemsVM);
        }

        public virtual ActionResult Details(int id)
        {
            EQUIPO equipo = db.EQUIPO.Find(id);
            INSUMO insumo = db.INSUMO.Find(id);

            if (equipo != null)
            {
                return RedirectToAction(MVC.Equipo.Details(id));
            }
            else if (insumo != null)
            {
                return RedirectToAction(MVC.Insumo.Details(id));
            }
            else
            {
                this.ShowMessage(MessageType.Warning, "No se encontró un equipo o insumo asociado a este ítem.");
                return View(db.ITEM.Find(id));
            }
        }

        public virtual ActionResult Edit(int id)
        {
            EQUIPO equipo = db.EQUIPO.Find(id);
            INSUMO insumo = db.INSUMO.Find(id);

            if (equipo != null)
            {
                return RedirectToAction(MVC.Equipo.Edit(id));
            }
            else if (insumo != null)
            {
                return RedirectToAction(MVC.Insumo.Edit(id));
            }
            else
            {
                //ViewBag.TIPO1 = new SelectList(db.TIPO, "TIPO1", "TIPO1");
                //ViewBag.SUBTIPO1 = new SelectList(db.SUB_TIPO, "SUBTIPO", "SUBTIPO");
                this.ShowMessage(MessageType.Warning, "No se encontró un equipo o insumo asociado a este ítem.");
                return View(db.ITEM.Find(id));
            }
        }

        [HttpPost]
        public virtual ActionResult Edit(ITEM item)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    db.Entry(item).State = EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Cambios guardados correctamente.");
                    return RedirectToAction("Index");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un error al intentar guardar los cambios.");
                    //ViewBag.TIPO1 = new SelectList(db.TIPO, "TIPO1", "TIPO1");
                    //ViewBag.SUBTIPO1 = new SelectList(db.SUB_TIPO, "SUBTIPO", "SUBTIPO");
                    return View(item);
                }
            }

            this.ShowMessage(MessageType.Warning, "Datos incorrectos, dañados o error durante su transmisión.");
            //ViewBag.TIPO1 = new SelectList(db.TIPO, "TIPO1", "TIPO1");
            //ViewBag.SUBTIPO1 = new SelectList(db.SUB_TIPO, "SUBTIPO", "SUBTIPO");
            return View(item);
        }

        public virtual ActionResult Delete(int id)
        {
            EQUIPO equipo = db.EQUIPO.Find(id);
            INSUMO insumo = db.INSUMO.Find(id);

            if (equipo != null)
            {
                return RedirectToAction(MVC.Equipo.Delete(id));
            }
            else if (insumo != null)
            {
                return RedirectToAction(MVC.Insumo.Delete(id));
            }
            else
            {
                this.ShowMessage(MessageType.Warning, "No se encontró un equipo o insumo asociado a este ítem.");
                return View(db.ITEM.Find(id));
            }
        }

        [HttpPost, ActionName("Delete")]
        public virtual ActionResult DeleteConfirmed(int id)
        {
            EQUIPO equipo = db.EQUIPO.Find(id);
            INSUMO insumo = db.INSUMO.Find(id);

            //VA A REDIRIGIR A LOS CONTROLADORES DE EQUIPO O INSUMO.
            if (equipo != null)
            {
                return RedirectToAction(MVC.Equipo.DeleteConfirmed(id));
            }
            else if (insumo != null)
            {
                return RedirectToAction(MVC.Insumo.DeleteConfirmed(id));
            }
            else
            {
                ITEM item = db.ITEM.Find(id);
                db.ITEM.Remove(item);
                db.SaveChanges();

                this.ShowMessage(MessageType.Warning, "No se encontró un equipo o insumo asociado a este ítem.");
                this.ShowMessage(MessageType.Success, "El ítem fue eliminado exitosamente.");
                return View(db.ITEM.Find(id));
            }
        }

        #endregion

        #region Validaciones

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaBusquedaVacia(string Criterios, string AreaBusqueda)
        {
            switch (Criterios)
            {
                case "Codigo":
                    int codigo;
                    if (Int32.TryParse(AreaBusqueda, out codigo))
                    {
                        return db.ITEM.Any(c => c.CODIGO_ITEM == codigo) ?
                               Json(true, JsonRequestBehavior.AllowGet) :
                               Json("No se encontraron ítems con el código ingresado", JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        return Json("El código ingresado no es correcto (no puede contener letras, sólo números)", JsonRequestBehavior.AllowGet);
                    }
                case "Tipo":
                    bool hayEquiposTipo = db.EQUIPO.Any(e => e.TIPO_EQUIPO.Contains(AreaBusqueda));
                    bool hayInsumosTipo = db.INSUMO.Any(i => i.TIPO_INSUMO.Contains(AreaBusqueda));

                    if (hayEquiposTipo || hayInsumosTipo)
                    {
                        return Json(true, JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        return Json("No se econtraron items con el tipo ingresado", JsonRequestBehavior.AllowGet);
                    }
                case "Marca":
                    if (db.ITEM.Any(i => i.MARCA.Contains(AreaBusqueda)))
                    {
                        return Json(true, JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        return Json("No se encontraron items con la marca ingresada", JsonRequestBehavior.AllowGet);
                    }
                case "Modelo":
                    if (db.ITEM.Any(i => i.MODELO.Contains(AreaBusqueda)))
                    {
                        return Json(true, JsonRequestBehavior.AllowGet);
                    }
                    else
                    {
                        return Json("No se encontraron items con el modelo ingresado", JsonRequestBehavior.AllowGet);
                    }
                default:
                    return Json("Criterio de búsqueda desconocido", JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #region Busqueda

        [ChildActionOnly]
        public virtual ActionResult Search()
        {
            return PartialView();
        }

        public virtual ActionResult Busqueda()
        {
            return View();
        }

        public virtual ActionResult ResultadoBusqueda(string Criterios, string AreaBusqueda)
        {
            switch (Criterios)
            {
                case "Codigo":
                    int codigo;
                    return View(new ResultadoBusquedaItemViewModel
                    {
                        Resultado = Int32.TryParse(AreaBusqueda, out codigo) ?
                                    db.ITEM.Where(c => c.CODIGO_ITEM == codigo).ToList() :
                                    new List<ITEM>(),
                        CriterioParaOrdenar = Criterios
                    });
                case "Tipo":
                    List<ITEM> itemsTipo = new List<ITEM>();
                    var equiposTipo = db.EQUIPO.Where(e => e.TIPO_EQUIPO.Contains(AreaBusqueda)).Select(e => e.ITEM).ToList();
                    var insumosTipo = db.INSUMO.Where(i => i.TIPO_INSUMO.Contains(AreaBusqueda)).Select(i => i.ITEM).ToList();

                    itemsTipo.Concat(equiposTipo).Concat(insumosTipo);

                    return View(new ResultadoBusquedaItemViewModel
                        {
                            Resultado = itemsTipo,
                            CriterioParaOrdenar = Criterios
                        });
                case "Marca":
                    return View(new ResultadoBusquedaItemViewModel
                        {
                            Resultado = db.ITEM.Where(i => i.MARCA.Contains(AreaBusqueda)),
                            CriterioParaOrdenar = Criterios
                        });

                case "Modelo":
                    return View(new ResultadoBusquedaItemViewModel
                        {
                            Resultado = db.ITEM.Where(i => i.MODELO.Contains(AreaBusqueda)),
                            CriterioParaOrdenar = Criterios
                        });
                default:
                    return PartialView(Views.Search);
            }
        }

        #endregion

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}